<template>
  <div class="page-box">

    <el-form class="search" label-width="70px">
      <el-form-item label="账号">
        <el-input v-model="listModel.userAccount" placeholder="账号" clearable />
      </el-form-item>
      <el-form-item label="姓名">
        <el-input v-model="listModel.userName" placeholder="姓名" clearable />
      </el-form-item>
      <el-form-item label="手机号">
        <el-input v-model="listModel.userMobile" placeholder="手机号" clearable />
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker
            v-model="createTimeRange"
            type="daterange"
            range-separator="-"
            start-placeholder="开始"
            end-placeholder="结束"
            @change="createTimeChange"
            clearable
        />
      </el-form-item>
      <el-form-item class="search-btn">
        <el-button type="primary" icon="Search" @click="pageSizeChange">搜索</el-button>
        <el-button icon="RefreshRight" @click="resetList">重置</el-button>
      </el-form-item>
    </el-form>

    <div class="head">
      <span class="title">系统用户管理</span>
      <div class="toolbar">
        <el-button type="primary" icon="Plus" @click="addOrModify(null)">添加</el-button>
        <el-button type="primary" icon="Refresh" @click="fetchListData">刷新</el-button>
        <el-button type="danger" icon="Delete" @click="isShowDelDialog = true">批量删除</el-button>
      </div>
    </div>

    <div class="table">
      <el-table
          stripe
          v-loading="loading"
          :data="listData"
          row-key="id"
          @selection-change="selectionChange"
      >
        <el-table-column type="selection" width="30" />
        <el-table-column prop="userAccount" label="账号" />
        <el-table-column prop="userName" label="姓名" />
        <el-table-column prop="userMobile" label="手机号" width="110" />
        <el-table-column prop="userStatus" label="状态" #default="{ row }">
          {{ row.userStatus === 1 ? '正常' : '禁用' }}
        </el-table-column>
        <el-table-column prop="created" label="创建时间" align="right" width="138" />
        <el-table-column prop="updated" label="修改时间" width="138" />
        <el-table-column label="操作" fixed="right" width="200" align="center" #default="{ row }">
          <el-button type="primary" icon="Plus" @click="assign(row)" />
          <el-button type="primary" icon="Edit" @click="addOrModify(row)" />
          <el-button type="danger" icon="Delete" @click="del(row.id)" />
        </el-table-column>
      </el-table>
    </div>
    <el-pagination
        class="pagination"
        v-model:current-page="listModel.current"
        v-model:page-size="listModel.size"
        :page-sizes="[10, 30, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="pageSizeChange"
        @current-change="fetchListData"
    />

    <el-drawer
        size="36%"
        :title="addOrModifyDrawerTitle"
        v-model="isShowAddOrModifyDrawer"
        direction="rtl"
        :before-close="addOrModifyDrawerClose"
        @opened="addOrModifyDrawerOpened(addOrModifyFormRef)"
    >
      <div class="form-content">
        <el-form ref="addOrModifyFormRef" label-width="70px" :model="addOrModifyModel" :rules="addOrModifyRules">
          <el-form-item label="账号" prop="userAccount">
            <el-input v-model="addOrModifyModel.userAccount" placeholder="管理员账号" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="密码" prop="userPassword">
            <el-input type="password" show-password v-model="addOrModifyModel.userPassword" placeholder="管理员密码" autocomplete="off" />
          </el-form-item>
          <el-form-item label="状态">
            <el-switch v-model="status" />
          </el-form-item>
          <el-form-item label="姓名" prop="userName">
            <el-input v-model="addOrModifyModel.userName" placeholder="管理员姓名" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="手机号" prop="userMobile">
            <el-input v-model="addOrModifyModel.userMobile" placeholder="管理员手机号" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="头像" prop="userMobile">
            <el-input v-model="addOrModifyModel.userAvatar" placeholder="上传或者在这里填写头像地址" autocomplete="off" clearable />
          </el-form-item>
          <el-form-item label="头像" prop="userAvatar">
            <el-upload
                :data="{usage: 'admin-avatar'}"
                class="avatar-uploader"
                :headers="headers"
                :action="uploadUrl"
                :on-success="uploadSuccessHandle"
                :show-file-list="false"
            >
              <img v-if="imgUrl" :src="imgUrl" class="avatar"  alt="头像"/>
              <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="loading" @click="doAddOrModify">
              {{ loading ? '正在提交 ...' : '提交' }}
            </el-button>
            <el-button @click="addOrModifyDrawerClose">取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-drawer>

    <el-drawer
        size="50%"
        title="分配角色"
        v-model="isShowAssignDrawer"
        :before-close="assignDrawerClose"
        direction="rtl"
    >
      <div class="form-content">
        <el-form label-width="70px">
          <el-form-item label="账号">
            <el-input v-model="userInfo.userAccount" disabled />
          </el-form-item>
          <el-form-item label="姓名">
            <el-input v-model="userInfo.userName" disabled />
          </el-form-item>
          <el-form-item label="角色">
            <el-checkbox
                v-model="isCheckAllRole"
                :indeterminate="isNotCheckAllRole"
                @change="checkAllRoleHandle"
            >
              全选
            </el-checkbox>
            <el-checkbox-group v-model="assignedRoles" @change="checkRoleHandle">
              <el-checkbox v-for="role in roles" :key="role.id" :label="role.id">
                {{ role.roleName }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :loading="loading" @click="doAssign">
              {{ loading ? '正在提交 ...' : '提交' }}
            </el-button>
            <el-button @click="assignDrawerClose">取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-drawer>

    <el-dialog
        v-model="isShowDelDialog"
        title="提示"
        width="30%"
        :before-close="delDialogClose"
    >
      <span>确定要删除吗？</span>
      <template #footer>
        <span>
          <el-button @click="delDialogClose">取消</el-button>
          <el-button type="primary" :loading="loading" @click="doDel">
            {{ loading ? '正在删除 ...' : '确定' }}
          </el-button>
        </span>
      </template>
    </el-dialog>

  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useApp } from '@/pinia/modules/app'
import { GetListData, AddData, ModifyData, DeleteData } from '@/api/system/sysUser'
import { GetAssignedRoles, AssignRoles } from '@/api/system/sysRole'
import { parseRangeDateTime } from "@/utils"
import { uploadPictureUrl, RemoveFile } from '@/api/upload'

const loading = ref(false)

/* 列表开始 */
const createTimeRange = ref('')
const total = ref(0)
const listModelData = {
  current: 1,
  size: Number(import.meta.env.VITE_PAGE_SIZE),
  userAccount: '',
  userName: '',
  userMobile: '',
  createBeginTime: '',
  createEndTime: '',
}
const listModel = ref({ ...listModelData })
const listData = ref([])

const fetchListData = async () => {
  if (loading.value) {
    return
  }
  loading.value = true
  const { code, message, data } = await GetListData(listModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  listData.value = data.records
  total.value = Number(data.total)
}

const createTimeChange = v => {
  const t = parseRangeDateTime(v)
  listModel.value.createBeginTime = t[0]
  listModel.value.createEndTime = t[1]
}

const pageSizeChange = () => {
  listModel.value.current = 1
  fetchListData()
}

const resetList = () => {
  listModel.value = { ...listModelData }
  fetchListData()
}

onMounted(() => {
  fetchListData()
})
/* 列表结束 */

/* 分配角色开始 */
const userInfo = ref({})
const isShowAssignDrawer = ref(false)
const isCheckAllRole = ref(false)
const isNotCheckAllRole = ref(true)
const roles = ref([])
const assignedRoles = ref([])
const assignRoleModel = ref([])

const resetAssignDrawer = () => {
  userInfo.value = {}
  assignRoleModel.value = []
  roles.value = []
  assignedRoles.value = []
  loading.value = false
}

const assignDrawerClose = () => {
  if (loading.value) {
    return
  }
  resetAssignDrawer()
  isShowAssignDrawer.value = false
}

const assign = async row => {
  isShowAssignDrawer.value = true
  userInfo.value = { ...row }
  const { code, message, data } = await GetAssignedRoles(row.id)
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  roles.value = data.roles
  assignedRoles.value = data.assignedRoles
}

const doAssign = async () => {
  if (loading.value) {
    return
  }
  loading.value = true
  assignRoleModel.value = []
  assignedRoles.value.forEach(item => {
    assignRoleModel.value.push({
      userId: userInfo.value.id,
      roleId: item,
    })
  })
  const { code, message } = await AssignRoles(assignRoleModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  isShowAssignDrawer.value = false
  resetAssignDrawer()
  ElMessage.success(message)
}

const checkAllRoleHandle = val => {
  if (val) {
    roles.value.forEach(item => assignedRoles.value.push(item.id))
  } else {
    assignedRoles.value = []
  }
  isNotCheckAllRole.value = false
}

const checkRoleHandle = arr => {
  const count = arr.length
  isCheckAllRole.value = count === roles.value.length
  isNotCheckAllRole.value = count > 0 && count < roles.value.length
}
/* 分配角色结束 */

/* 上传头像开始 */
const { authorization } = useApp()
const headers = ref({ token: authorization.token })
const fileServerUrl = ref(import.meta.env.VITE_FILE_SERVER_URL)
const imgUrl = ref()
const uploadUrl = ref(uploadPictureUrl)

const uploadSuccessHandle = res => {
  const { code, message, data } = res
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  const fileName = addOrModifyModel.value.userAvatar
  if (fileName.length > 0 && !fileName.startsWith('http:') && !fileName.startsWith('https:')) {
    RemoveFile({
      fileNames: [fileName]
    })
  }
  addOrModifyModel.value.userAvatar = data.url
  imgUrl.value = `${fileServerUrl.value}${data.url}`
}
/* 上传头像结束 */

/* 添加修改开始 */
const status = ref(true)
const addOrModifyFormRef = ref()
const addOrModifyDrawerTitle = ref('')
const isShowAddOrModifyDrawer = ref(false)

const addOrModifyData = {
  userAccount: '',
  userPassword: '',
  userName: '',
  userMobile: '',
  userStatus: 1,
  userAvatar: '',
}
const addOrModifyModel = ref({ ...addOrModifyData })

const addOrModifyRules = ref({
  userAccount: [{ required: true, message: '请输入账号', trigger: 'blur' }],
  userPassword: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 12, message: '密码的长度应该在 6 ~ 12 位', trigger: 'blur' },
  ],
  userName: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  userMobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
  userAvatar: [{ required: true, message: '请上传头像', trigger: 'blur' }],
})

const addOrModify = (row) => {
  if (row == null) {
    addOrModifyDrawerTitle.value = '添加用户'
  } else {
    addOrModifyRules.value.userPassword[0].required = false
    status.value = row.userStatus === 1
    imgUrl.value = `${fileServerUrl.value}${row.userAvatar}`
    addOrModifyDrawerTitle.value = '编辑用户'
    addOrModifyModel.value = { ...row }
    delete addOrModifyModel.value.created
    delete addOrModifyModel.value.updated
  }
  isShowAddOrModifyDrawer.value = true
}

const doAddOrModify = () => {
  if (loading.value) {
    return
  }
  addOrModifyFormRef.value.validate(async valid => {
    if (!valid) {
      return
    }
    loading.value = true
    addOrModifyModel.value.userStatus = status.value ? 1 : 0
    let code, message
    if (addOrModifyModel.value.id) {
      const result = await ModifyData(addOrModifyModel.value)
      code = result.code
      message = result.message
    } else {
      const result = await AddData(addOrModifyModel.value)
      code = result.code
      message = result.message
    }
    loading.value = false
    if (code !== 200) {
      ElMessage.error(message)
      return
    }
    isShowAddOrModifyDrawer.value = false
    resetAddOrModify()
    await fetchListData()
    ElMessage.success(message)

  })
}

const addOrModifyDrawerOpened = formEl => {
  formEl.clearValidate()
}

const resetAddOrModify = () => {
  status.value = true
  imgUrl.value = ''
  addOrModifyRules.value.userPassword[0].required = true
  addOrModifyFormRef.value.resetFields()
  addOrModifyModel.value = { ...addOrModifyData }
  loading.value = false
}
const addOrModifyDrawerClose = () => {
  if (loading.value) {
    return
  }
  resetAddOrModify()
  isShowAddOrModifyDrawer.value = false
}
/* 添加修改结束 */

/* 删除开始 */
const isShowDelDialog = ref(false)
const delModel = ref({ ids: [] })

const del = id => {
  delModel.value.ids.push(id)
  isShowDelDialog.value = true
}

const doDel = async () => {
  if (loading.value) {
    return
  }
  if (delModel.value.ids.length <= 0) {
    ElMessage.error('请至少选择一项')
    return
  }
  loading.value = true
  const { code, message } = await DeleteData(delModel.value)
  loading.value = false
  if (code !== 200) {
    ElMessage.error(message)
    return
  }
  isShowDelDialog.value = false
  resetDel()
  await fetchListData()
  ElMessage.success(message)
}

const resetDel = () => {
  delModel.value.ids = []
  loading.value = false
}

const delDialogClose = () => {
  if (loading.value) {
    return
  }
  resetDel()
  isShowDelDialog.value = false
}

const selectionChange = arr => {
  delModel.value.ids = []
  arr.forEach(row => {
    delModel.value.ids.push(row.id)
  })
}
/* 删除结束 */
</script>

<style scoped lang="scss">
.page-box {
  width: 100%;
  box-sizing: border-box;
  .search {
    padding: 20px 20px 0;
    background: #fff;
    margin-bottom: 10px;
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      margin: {
        bottom: 20px;
      }
    }
    .search-btn {
      margin-left: auto;
    }
    :deep(.el-input-number .el-input__inner) {
      text-align: left;
    }
    :deep(.el-range-editor.el-input__wrapper) {
      box-sizing: border-box;
    }
  }
  .head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 20px 0;
    background: #fff;
    .title {
      font-size: 16px;
    }
  }
  .table {
    padding: 20px;
    background: #fff;
  }
  .pagination {
    padding: 0 20px 20px;
    background: #fff;
    justify-content: flex-end;
    :last-child {
      margin-right: 0;
    }
  }
}

:deep(.el-checkbox) {
  width: 120px;
}
.form-content {
  /* 上传组件的样式开始 */
  .avatar-uploader {
    :deep(.el-upload) {
      border: 1px dashed var(--el-border-color);
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: var(--el-transition-duration-fast);
    }
    :deep(.el-upload:hover) {
      border-color: var(--el-color-primary);
    }
    :deep(.avatar-uploader-icon) {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      text-align: center;
    }
    :deep(img) {
      width: 178px;
      height: 178px;
    }
  }
  /* 上传组件的样式结束 */
}
</style>
